﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using log4net.Config;
using System.IO;
using log4net.Core;
using System.Reflection;
using System.Xml.Linq;

//[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
namespace Tencent.OA.App
{
    internal class Log4Net : ILogger
    {
        private static ILog m_logger; 
       
        /// <summary>
        /// 构造函数
        /// </summary>
        static Log4Net()
        {           
            //应用新配置到log4net.config
            //TencentConfigurationSectionGroup configSection = TencentConfigurationSectionGroup.GetSectionGroup();
            //ModifyLog4netConfig(configSection.Logger);
            log4net.Config.XmlConfigurator.Configure();
            //log4net.Config.DOMConfigurator.Configure(new FileInfo(Path.Combine(AssemblyInfo.GetAssemblyPath()/*AppDomain.CurrentDomain.BaseDirectory*/, "log4net.config")));
            m_logger = LogManager.GetLogger(typeof(Log4Net));            
        }
        /// <summary>
        /// 写日志信息。
        /// </summary>
        /// <param name="message">日志文本</param>
        private void Log(string message)
        {
            Log(message, LogLevel.DEBUG);
        }
        /// <summary>
        /// 写异常信息。
        /// </summary>
        /// <param name="message">异常对象。</param>
        private void Log(Exception exp)
        {
            Log(exp, LogLevel.DEBUG);
        }
        /// <summary>
        /// 写日志信息。
        /// </summary>
        /// <param name="message">日志文本。</param>
        /// <param name="level">日志级别。</param>
        private void Log(string message, LogLevel level)
        {
            //Log4Net logger = new Log4Net();
            Write(message, level);
        }
        /// <summary>
        /// 写异常信息。
        /// </summary>
        /// <param name="exception">异常对象。</param>
        /// <param name="level">日志级别。</param>
        private void Log(Exception exception, LogLevel level)
        {
            //Log4Net logger = new Log4Net();
            Write(exception.Message, exception, level);
        }

        private void Write(string message, LogLevel level)
        {
            #region
            switch (level)
            {
                case LogLevel.FATAL:
                    m_logger.Fatal(message);
                    return;

                case LogLevel.WARN:
                    m_logger.Warn(message);
                    return;

                case LogLevel.INFO:
                    m_logger.Info(message);
                    return;

                case LogLevel.DEBUG:
                    m_logger.Debug(message);
                    return;

                case LogLevel.ERROR:
                    m_logger.Error(message);
                    return;
            }

            #endregion

        }

        private void Write(string message, Exception exp, LogLevel level)
        {
            #region
            switch (level)
            {
                case LogLevel.FATAL:
                    m_logger.Fatal(message, exp);
                    return;

                case LogLevel.WARN:
                    m_logger.Warn(message, exp);
                    return;

                case LogLevel.INFO:
                    m_logger.Info(message, exp);
                    return;

                case LogLevel.DEBUG:
                    m_logger.Debug(message, exp);
                    return;

                case LogLevel.ERROR:
                    m_logger.Error(message, exp);
                    return;
            }
            #endregion
        } 
        /// <summary>
        /// 根据应用程序配置文件修改log4net的配置文件。
        /// </summary>
        /// <param name="configSection">配置节点对象</param>     
        private static void ModifyLog4netConfig(LoggerSection configSection)
        {
            string configFilePath = Path.Combine(AssemblyInfo.GetAssemblyPath()/*AppDomain.CurrentDomain.BaseDirectory*/, "log4net.config");
            if (!File.Exists(configFilePath))
                throw new IOException("配置文件不存在：" + configFilePath);

            XElement doc = XElement.Load(configFilePath);
            //日志登记            
            var query = from o in doc.Descendants("log4net").Descendants("root").Descendants("level")
                        select o;
            XElement ele = query.First();
            ele.Attribute("value").SetValue(configSection.Level.GetEnumItemText());
            //文件路径
            query = from o in doc.Descendants("log4net").Descendants("appender").Descendants("file")
                    select o;
            query.First().Attribute("value").SetValue(configSection.LogFilePath);
            //输出文件格式
            query = from o in doc.Descendants("log4net").Descendants("appender").Descendants("datePattern")
                    select o;
            if (!string.IsNullOrEmpty(configSection.LogFileFormat))
                query.First().Attribute("value").SetValue(configSection.LogFileFormat);

            try
            {
                doc.Save(configFilePath);
            }
            catch (Exception e)
            {
                throw new IOException("无法将新配置应用到文件:" + configFilePath + "。");
            }
        }



        #region ILogger 成员

        public void Info(string message)
        {
            m_logger.Info(message);
        }

        public void Info(Exception ex)
        {
            m_logger.Info("Exception:", ex);
        }

        public void Error(string message)
        {
            m_logger.Error(message);
        }

        public void Error(Exception exception)
        {
            m_logger.Error("Error:",exception);
        }

        #endregion
    }
}
